package com.plat.controller;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.plat.core.hibernate.qbc.CriteriaQuery;
import com.plat.security.entity.SysUsers;
import com.plat.service.IBaseService;
import com.plat.tag.core.json.AjaxJson;
import com.plat.tag.core.json.AjaxUtils;
import com.plat.tag.core.json.DataGrid;
import com.plat.tag.core.utils.TagUtil;
import com.plat.util.MyBeanUtils;
import com.plat.util.StringUtil;
import com.plat.util.clazz.BeanUtils;
import com.plat.util.clazz.GenericsUtils;

@Controller("baseController")
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class BaseController<T> {

	public abstract IBaseService<T> getService();

	private T entity;

	protected Class<T> entityClass;

	protected Class idClass;

	protected static final String ID_NAME = "id";

	public T getEntity() {
		return entity;
	}

	public void setEntity(T entity) {
		this.entity = entity;
	}

	public Class<T> getEntityClass() {
		return entityClass;
	}

	public void setEntityClass(Class<T> entityClass) {
		this.entityClass = entityClass;
	}

	protected void getIdClazz() {
		try {
			entityClass = GenericsUtils.getSuperClassGenricType(getClass());
			idClass = BeanUtils.getPropertyType(entityClass, ID_NAME);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected Serializable getEntityId(String idString) {
		if (StringUtils.isEmpty(idString)) {
			return null;
		}
		try {
			// getIdClazz();
			return (Serializable) ConvertUtils.convert(idString, Long.class);
		} catch (NumberFormatException e) {
			throw new IllegalArgumentException("Wrong when get id from request");
		}
	}

	/**
	 * 获取用户的权限
	 * @param request
	 * @return
	 */
	protected List<String> getSessionAuthorities(HttpServletRequest request) {

		Authentication authentication = getSecurityContext(request).getAuthentication();

		Collection<GrantedAuthority> connect = authentication.getAuthorities();

		// 获取用户的权限集合
		List<String> authoritys = new ArrayList<String>();
		for (GrantedAuthority grant : connect) {
			authoritys.add(grant.getAuthority());
		}
		return authoritys;
	}

	/**
	 * 获取用户的角色
	 * @param request
	 * @return
	 */
	protected List<String> getSessionRoles(HttpServletRequest request) {

		List<String> authoritys = getSessionAuthorities(request);

		// 获取用户的权限集合
		List<String> roles = new ArrayList<String>();
		for (String auth : authoritys) {
			roles.add(auth.replace("AUTH_", "ROLE_"));
		}
		return roles;
	}

	/**
	 * 获取用户
	 * @param request
	 * @return
	 */
	protected SysUsers getUserDetails(HttpServletRequest request) {
		return (SysUsers) getSecurityContext(request).getAuthentication().getPrincipal();
	}

	protected SecurityContextImpl getSecurityContext(HttpServletRequest request) {
		return (SecurityContextImpl) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
	}

	@RequestMapping(params = "toListPage")
	protected ModelAndView toListPage(String pathroot, String page) {
		return new ModelAndView(pathroot + "/" + page);
	}

	/**
	 * easyui AJAX请求数据
	 * @param request
	 * @param response
	 * @param dataGrid
	 * @param user
	 */

	@RequestMapping(params = "list")
	@ResponseBody
	public String datagrid(T t, HttpServletRequest request, DataGrid dataGrid) {
		try {
			CriteriaQuery cq = new CriteriaQuery(t.getClass(), dataGrid);
			// 查询条件组装器
			HqlGenerateUtil.installHql(cq, t, request.getParameterMap());
			getService().getDataGridReturn(cq, true);
			JSONObject object = TagUtil.getJson(dataGrid);
			return object.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "{}";
	}

	@RequestMapping(params = "toEdit")
	public ModelAndView toEdit(String id, String root) {
		ModelAndView mv = new ModelAndView(root + "/add");
		try {
			if (StringUtil.isNotEmpty(id)) {
				T t = getService().get(getEntityId(id));
				mv.addObject("entity", t);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}

	@RequestMapping(params = "toTask")
	public ModelAndView toTask(String id, String root, T src) {
		ModelAndView mv = new ModelAndView(root + "/task");
		try {
			if (StringUtil.isNotEmpty(id)) {
				T t = getService().get(getEntityId(id));
				mv.addObject("entity", t);
				mv.addObject("src", src);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}

	@RequestMapping(params = "doDelete")
	@ResponseBody
	public AjaxJson doDelete(final String id) throws Exception {

		System.out.println(id);
		return new AjaxUtils() {

			@Override
			protected Object busCall() {
				getService().removeById(getEntityId(id));
				return null;
			}
		}.excuteJson("数据删除成功!", "数据删除失败");
	}

	@RequestMapping(params = "doSave")
	@ResponseBody
	public AjaxJson doSave(final T t) throws Exception {

		return new AjaxUtils() {

			@Override
			protected Object busCall() throws Exception {
				String id = BeanUtils.getProperty(t, ID_NAME);
				if (StringUtil.isNotEmpty(id)) {
					T entity = getService().get(getEntityId(id));

					MyBeanUtils.copyBeanNotNull2Bean(t, entity);
					getService().updateMerge(t);
				} else {
					getService().save(t);
				}
				return null;
			}
		}.excuteJson("操作成功!", "操作失败");
	}
}
